param(
    [string]$ISCCPath,
    [switch]$Verbose,
    [switch]$AutoInstall,
    [switch]$SilentInstall
)

function Write-Info($msg) { Write-Host "[INFO] $msg" -ForegroundColor Cyan }
function Write-Warn($msg) { Write-Host "[WARN] $msg" -ForegroundColor Yellow }
function Write-Err($msg) { Write-Host "[ERR]  $msg" -ForegroundColor Red }

function Get-IsccPath {
    if ($ISCCPath) {
        if (Test-Path $ISCCPath) { return $ISCCPath }
        else { Write-Warn "Provided ISCCPath not found: $ISCCPath" }
    }
    if ($env:ISCC_PATH) {
        if (Test-Path $env:ISCC_PATH) { return $env:ISCC_PATH }
    }
    $cmd = (Get-Command iscc -ErrorAction SilentlyContinue)
    if ($cmd) { return $cmd.Path }
    $candidates = @(
        "C:\Program Files\Inno Setup 6\ISCC.exe",
        "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"
    )
    foreach ($p in $candidates) { if (Test-Path $p) { return $p } }
    return $null
}

function Install-InnoSetup([switch]$Silent) {
    try {
        $temp = Join-Path $env:TEMP "innosetup-setup.exe"
        $url  = "https://jrsoftware.org/download.php/is.exe"
        Write-Info "Downloading Inno Setup from: $url"
        Invoke-WebRequest -Uri $url -OutFile $temp -UseBasicParsing
        if (-not (Test-Path $temp)) { Write-Err "Download failed."; return $false }
        if ($Silent) { $args = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-" } else { $args = "" }
        Write-Info "Starting installer..."
        if ($args) { Start-Process -FilePath $temp -ArgumentList $args -Wait }
        else { Start-Process -FilePath $temp -Wait }
        Remove-Item $temp -Force -ErrorAction SilentlyContinue
        return $true
    } catch {
        Write-Err ("Installation failed: " + $_.Exception.Message)
        return $false
    }
}

# 等待构建产物文件存在，避免在发布未完成时编译安装包
function Wait-ForFile([string]$path, [int]$timeoutSec = 60) {
    Write-Info "等待构建产物文件: $path"
    $sw = [System.Diagnostics.Stopwatch]::StartNew()
    while (-not (Test-Path $path)) {
        if ($sw.Elapsed.TotalSeconds -ge $timeoutSec) {
            Write-Err "等待文件超时: $path"
            return $false
        }
        Start-Sleep -Seconds 1
    }
    Write-Info "文件就绪: $path"
    return $true
}

# 读取InformationalVersion，优先从EXE的ProductVersion；如无则从csproj回退
function Get-InformationalVersion([string]$rootDir) {
    $releaseRoot = Join-Path $rootDir "bin/Release/net8.0"
    $exeNoRt  = Join-Path $releaseRoot "win-x64-no-runtime/LocalDnsService.exe"
    $exeWithRt = Join-Path $releaseRoot "win-x64-with-runtime/LocalDnsService.exe"
    $version = $null
    foreach ($p in @($exeWithRt, $exeNoRt)) {
        if (Test-Path $p) {
            $fvi = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($p)
            if ($fvi.ProductVersion -and $fvi.ProductVersion -ne "0.0.0.0") { $version = $fvi.ProductVersion; break }
        }
    }
    if (-not $version) {
        $csproj = Join-Path $rootDir "LocalDnsService.csproj"
        if (Test-Path $csproj) {
            $xml = Get-Content $csproj -Raw
            $m = [regex]::Match($xml, '<InformationalVersion>(.*?)</InformationalVersion>')
            if ($m.Success) { $version = $m.Groups[1].Value }
            if (-not $version) {
                $m2 = [regex]::Match($xml, '<Version>(.*?)</Version>')
                if ($m2.Success) { $version = $m2.Groups[1].Value }
            }
        }
    }
    if (-not $version) { $version = "1.0.0" }
    return $version
}

$root = $PSScriptRoot
Set-Location $root

Write-Info "Searching for Inno Setup Compiler (ISCC.exe)..."
$iscc = Get-IsccPath
if (-not $iscc) {
    Write-Warn "Inno Setup Compiler (ISCC.exe) not found."
    $proceed = $false
    if ($AutoInstall) {
        $proceed = $true
    } else {
        $answer = Read-Host "Download and install Inno Setup 6 now? (Y/N)"
        if ($answer -match '^(Y|y)$') { $proceed = $true }
    }
    if ($proceed) {
        $installed = Install-InnoSetup -Silent:$SilentInstall
        if ($installed) { $iscc = Get-IsccPath }
    } else {
        Write-Warn "Install aborted by user. Download: https://jrsoftware.org/isdl.php"
        exit 0
    }
    if (-not $iscc) {
        Write-Err "ISCC not found after installation attempt."
        exit 1
    }
}
Write-Info "Found ISCC: $iscc"

$noRuntimeIss = Join-Path $root "setup-no-runtime.iss"
$withRuntimeIss = Join-Path $root "setup-with-runtime.iss"

if (!(Test-Path $noRuntimeIss) -or !(Test-Path $withRuntimeIss)) {
    Write-Err "Missing Inno Setup script files."
    Write-Err "Expected: $noRuntimeIss and $withRuntimeIss"
    exit 1
}

# 在编译安装包前，确认发布输出中的EXE已经生成
$releaseRoot = Join-Path $root "bin\Release\net8.0"
$exeNoRuntime  = Join-Path $releaseRoot "win-x64-no-runtime\LocalDnsService.exe"
$exeWithRuntime = Join-Path $releaseRoot "win-x64-with-runtime\LocalDnsService.exe"

if (-not (Wait-ForFile $exeNoRuntime 60)) { exit 1 }
if (-not (Wait-ForFile $exeWithRuntime 60)) { exit 1 }

$infoVersion = Get-InformationalVersion $root
Write-Info "使用InformationalVersion: $infoVersion"

Write-Info "Compiling installer (no runtime)..."
& $iscc $noRuntimeIss ("/DMyAppVersion=" + $infoVersion) | Out-Host
Write-Info "Compiling installer (with runtime)..."
& $iscc $withRuntimeIss ("/DMyAppVersion=" + $infoVersion) | Out-Host

Write-Info "Installer build steps completed. Check bin\\Release output directory."